#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Ford UK NGc2 爬虫Bodystyle模块
专门处理车身样式配置的抓取和数据提取
"""

import time
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException


class BodystyleHandler:
    """Bodystyle配置处理器"""
    
    def __init__(self, driver, wait, navigation_handler):
        """
        初始化Bodystyle处理器
        
        Args:
            driver: WebDriver实例
            wait: WebDriverWait实例
            navigation_handler: 导航处理器实例
        """
        self.driver = driver
        self.wait = wait
        self.navigation_handler = navigation_handler
    
    def scrape_bodystyle_for_all_drives(self, drive_options):
        """
        为所有Drive选项抓取对应的Bodystyle数据
        
        Args:
            drive_options (list): Drive选项列表
            
        Returns:
            dict: 以Drive名称为key，Bodystyle选项列表为value的字典
        """
        print("  🚙 开始为所有Drive抓取Bodystyle数据...")
        
        all_bodystyle_data = {}
        
        for i, drive_option in enumerate(drive_options, 1):
            drive_name = drive_option.get('name', f'Drive_{i}')
            print(f"    🎯 处理Drive {i}/{len(drive_options)}: {drive_name}")
            
            try:
                # 选择当前Drive
                from .drive_handler import DriveHandler
                drive_handler = DriveHandler(self.driver, self.wait, self.navigation_handler)
                
                if drive_handler.select_drive_option(drive_option):
                    # 导航到Bodystyle页面
                    if self.navigate_to_bodystyle_page():
                        # 抓取当前Drive下的Bodystyle数据
                        bodystyle_data = self.scrape_bodystyle_data()
                        
                        if bodystyle_data:
                            all_bodystyle_data[drive_name] = bodystyle_data
                            print(f"      ✅ 为Drive '{drive_name}' 抓取到 {len(bodystyle_data)} 个Bodystyle")
                        else:
                            print(f"      ⚠️  Drive '{drive_name}' 未找到Bodystyle数据")
                    else:
                        print(f"      ❌ 无法进入Bodystyle页面 (Drive: {drive_name})")
                else:
                    print(f"      ❌ 无法选择Drive: {drive_name}")
                    
            except Exception as e:
                print(f"      ❌ 处理Drive '{drive_name}' 的Bodystyle时出错: {e}")
                continue
        
        print(f"  ✅ 完成所有Drive的Bodystyle抓取，共获得 {len(all_bodystyle_data)} 个Drive的数据")
        return all_bodystyle_data
    
    def navigate_to_bodystyle_page(self):
        """
        导航到Bodystyle配置页面
        
        Returns:
            bool: 是否成功进入Bodystyle页面
        """
        print(f"        🧭 导航到Bodystyle页面...")
        
        try:
            # 等待页面更新后再导航
            time.sleep(2)
            
            # 方法1：查找导航栏中的Bodystyle按钮
            nav_state = self.navigation_handler.get_navigation_state()
            if nav_state and 'Bodystyle' in nav_state:
                bodystyle_nav_info = nav_state['Bodystyle']
                
                if (bodystyle_nav_info.get('enabled', False) and 
                    not bodystyle_nav_info.get('current', False)):
                    
                    bodystyle_element = bodystyle_nav_info['element']
                    print(f"        ✓ 找到Bodystyle导航按钮")
                    
                    self.driver.execute_script("arguments[0].click();", bodystyle_element)
                    time.sleep(2)
                    
                    if self.verify_bodystyle_page_loaded():
                        print("        ✅ 通过导航栏进入Bodystyle页面")
                        return True
            
            # 方法2：直接查找Bodystyle相关链接
            bodystyle_selectors = [
                'a[href*="bodystyle"]',
                'a[href*="body-style"]',
                'button[data-testid*="bodystyle"]',
                '[class*="bodystyle"] a',
                'nav a:contains("Bodystyle")',
                'nav a:contains("Body Style")'
            ]
            
            for selector in bodystyle_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    for element in elements:
                        if element.is_displayed() and element.is_enabled():
                            print(f"        ✓ 找到Bodystyle链接: {selector}")
                            element.click()
                            time.sleep(2)
                            
                            if self.verify_bodystyle_page_loaded():
                                print("        ✅ 通过直接链接进入Bodystyle页面")
                                return True
                except Exception:
                    continue
            
            # 方法3：检查当前URL是否已经在Bodystyle页面
            current_url = self.driver.current_url.lower()
            if 'bodystyle' in current_url or 'body-style' in current_url:
                print("        ✓ 当前URL显示已在Bodystyle页面")
                return self.verify_bodystyle_page_loaded()
            
            print("        ❌ 所有Bodystyle导航方法都失败")
            return False
            
        except Exception as e:
            print(f"        ❌ 导航到Bodystyle页面时出错: {e}")
            return False
    
    def verify_bodystyle_page_loaded(self):
        """
        验证Bodystyle页面是否已加载
        
        Returns:
            bool: 是否已加载Bodystyle页面
        """
        try:
            # 检查方法1：查找Bodystyle相关的页面元素
            bodystyle_indicators = [
                'div[data-testid*="bodystyle"]',
                '[class*="bodystyle-option"]',
                'button[class*="BodystyleOption"]',
                '[class*="ProductTile"][class*="Bodystyle"]',
                'strong[class*="ProductTileAttributeValue"]'  # 根据用户澄清的业务逻辑
            ]
            
            for selector in bodystyle_indicators:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements:
                        print(f"          ✓ Bodystyle页面验证成功: 找到 {len(elements)} 个Bodystyle元素")
                        return True
                except Exception:
                    continue
            
            # 检查方法2：页面标题或URL
            current_url = self.driver.current_url.lower()
            page_title = self.driver.title.lower()
            
            if 'bodystyle' in current_url or 'body-style' in current_url or 'bodystyle' in page_title:
                print("          ✓ Bodystyle页面验证成功: URL或标题包含bodystyle")
                return True
            
            # 检查方法3：导航状态
            nav_state = self.navigation_handler.get_navigation_state()
            if nav_state and ('Bodystyle' in nav_state or 'Body Style' in nav_state):
                bodystyle_key = 'Bodystyle' if 'Bodystyle' in nav_state else 'Body Style'
                if nav_state[bodystyle_key].get('current', False):
                    print("          ✓ Bodystyle页面验证成功: 导航状态显示当前在Bodystyle页面")
                    return True
            
            print("          ❌ Bodystyle页面验证失败")
            return False
            
        except Exception as e:
            print(f"          ❌ 验证Bodystyle页面时出错: {e}")
            return False
    
    def scrape_bodystyle_data(self):
        """
        抓取当前页面的Bodystyle数据
        
        Returns:
            list: Bodystyle选项列表
        """
        print("            🔍 开始抓取Bodystyle选项...")
        
        try:
            bodystyle_options = []
            
            # 等待页面稳定
            time.sleep(2)
            
            # 根据用户澄清的业务逻辑：只有ProductTileAttributeValue标签内的内容才是BodyStyle
            bodystyle_attribute_selector = 'strong.ProductTileSection__ProductTileAttributeValue-sc-5noent-23'
            
            # 查找所有BodyStyle属性值元素
            bodystyle_elements = self.driver.find_elements(By.CSS_SELECTOR, bodystyle_attribute_selector)
            
            print(f"            🔍 找到 {len(bodystyle_elements)} 个ProductTileAttributeValue元素")
            
            for i, bodystyle_element in enumerate(bodystyle_elements, 1):
                if bodystyle_element.is_displayed():
                    bodystyle_text = bodystyle_element.text.strip()
                    
                    if bodystyle_text and len(bodystyle_text) > 1:  # 过滤掉过短的文本
                        # 提取价格信息（查找父容器中的价格信息）
                        price_info = self.extract_bodystyle_price_info(bodystyle_element)
                        
                        bodystyle_option = {
                            'name': bodystyle_text,
                            'price': price_info if price_info else 'Standard',
                            'description': '',
                            'element': bodystyle_element
                        }
                        
                        bodystyle_options.append(bodystyle_option)
                        print(f"              ✓ 提取Bodystyle {i}: {bodystyle_text} - {price_info}")
            
            if not bodystyle_options:
                print("            ⚠️  未找到有效的Bodystyle选项")
                # 使用备用抓取逻辑
                bodystyle_options = self.extract_bodystyle_options_fallback()
            
            return bodystyle_options
            
        except Exception as e:
            print(f"            ❌ 抓取Bodystyle数据时出错: {e}")
            return []
    
    def extract_bodystyle_price_info(self, bodystyle_element):
        """
        从Bodystyle元素中提取价格信息
        
        Args:
            bodystyle_element (WebElement): Bodystyle元素
            
        Returns:
            str: 价格信息
        """
        try:
            # 向上查找包含价格信息的父容器
            parent_selectors = [
                './ancestor::div[contains(@class, "ProductTile")][1]',
                './parent::*',
                './ancestor::div[1]'
            ]
            
            for parent_selector in parent_selectors:
                try:
                    parent_element = bodystyle_element.find_element(By.XPATH, parent_selector)
                    
                    # 在父容器中查找价格元素
                    price_selectors = [
                        'span:contains("£")',
                        '[class*="price"]',
                        'strong:contains("£")',
                        '*[text()[contains(., "£")]]'
                    ]
                    
                    for price_selector in price_selectors:
                        try:
                            price_elements = parent_element.find_elements(By.CSS_SELECTOR, price_selector)
                            for price_elem in price_elements:
                                price_text = price_elem.text.strip()
                                if '£' in price_text:
                                    return price_text
                        except Exception:
                            continue
                            
                except Exception:
                    continue
            
            return 'Standard'
            
        except Exception as e:
            print(f"              提取价格信息时出错: {e}")
            return 'Standard'
    
    def extract_bodystyle_options_fallback(self):
        """
        备用的Bodystyle选项提取方法
        
        Returns:
            list: Bodystyle选项列表
        """
        print("            🔄 使用备用方法提取Bodystyle选项...")
        
        try:
            bodystyle_options = []
            
            # 备用选择器
            fallback_selectors = [
                'div[data-testid*="bodystyle"]',
                '[class*="ProductTile"] strong',
                'button[class*="BodystyleOption"]',
                'div[role="radio"][class*="bodystyle"]'
            ]
            
            for selector in fallback_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    
                    if elements:
                        print(f"            使用备用选择器 '{selector}' 找到 {len(elements)} 个元素")
                        
                        for element in elements:
                            if element.is_displayed():
                                bodystyle_data = self.extract_bodystyle_option_data(element)
                                if bodystyle_data:
                                    bodystyle_options.append(bodystyle_data)
                        
                        if bodystyle_options:
                            break
                            
                except Exception:
                    continue
            
            return bodystyle_options
            
        except Exception as e:
            print(f"            备用方法提取时出错: {e}")
            return []
    
    def extract_bodystyle_option_data(self, element):
        """
        从Bodystyle选项元素中提取数据
        
        Args:
            element (WebElement): Bodystyle选项元素
            
        Returns:
            dict or None: Bodystyle选项数据
        """
        try:
            name = ''
            price = ''
            description = ''
            
            # 提取Bodystyle名称
            name_text = element.text.strip()
            if name_text:
                # 处理多行文本，取第一行作为名称
                lines = name_text.split('\n')
                for line in lines:
                    line = line.strip()
                    if line and not line.startswith('£'):  # 排除价格行
                        name = line
                        break
            
            # 提取价格信息
            try:
                price_elements = element.find_elements(By.CSS_SELECTOR, '*:contains("£")')
                for price_elem in price_elements:
                    price_text = price_elem.text.strip()
                    if '£' in price_text:
                        price = price_text
                        break
            except Exception:
                pass
            
            # 如果还没有价格，检查元素文本
            if not price and '£' in element.text:
                lines = element.text.split('\n')
                for line in lines:
                    if '£' in line:
                        price = line.strip()
                        break
            
            if not price:
                price = 'Standard'
            
            if name:
                return {
                    'name': name,
                    'price': price,
                    'description': description,
                    'element': element
                }
            
            return None
            
        except Exception as e:
            print(f"              提取Bodystyle选项数据时出错: {e}")
            return None
    
    def update_car_objects_with_bodystyle_data(self, car_series, target_model, all_bodystyle_data):
        """
        使用Bodystyle数据更新CarObject实例
        
        Args:
            car_series (CarSeries): 车系对象
            target_model (str): 目标车型名称
            all_bodystyle_data (dict): 所有Drive的Bodystyle数据
        """
        print(f"    🔄 为 {target_model} 的CarObject添加Bodystyle数据...")
        
        try:
            updated_objects = 0
            
            # 遍历所有CarObject，找到匹配的车型
            for car_object in car_series.car_object_list:
                if car_object.model_name.lower() == target_model.lower():
                    drive_name = car_object.drive
                    
                    # 查找对应Drive的Bodystyle数据
                    bodystyle_data = all_bodystyle_data.get(drive_name, [])
                    
                    if bodystyle_data:
                        # 添加每个Bodystyle选项
                        for bodystyle_option in bodystyle_data:
                            car_object.add_bodystyle(
                                bodystyle_name=bodystyle_option['name'],
                                associated_drive=drive_name,
                                price=bodystyle_option['price'],
                                description=bodystyle_option.get('description', '')
                            )
                        
                        updated_objects += 1
                        print(f"      ✓ 为 {target_model} + {drive_name} 添加 {len(bodystyle_data)} 个Bodystyle选项")
                    else:
                        print(f"      ⚠️  未找到Drive '{drive_name}' 的Bodystyle数据")
            
            print(f"    ✅ 共更新了 {updated_objects} 个CarObject，添加了Bodystyle数据")
            
        except Exception as e:
            print(f"    ❌ 更新CarObject时出错: {e}")